/*
 * Copyright 2009-2010 Nanjing RedOrange ltd (http://www.red-orange.cn)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package redora.client.ui;

import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.Cell;
import com.google.gwt.cell.client.ValueUpdater;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.EventTarget;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.safehtml.client.SafeHtmlTemplates;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;

/**
 * @author Nanjing Redorange (www.red-orange.cn)
 */
public class ImageActionCell<C> extends AbstractCell<C> {

    /**
     * The delegate that will handle events from the cell.
     *
     * @param <T> the type that this delegate acts on
     */
    public static interface Delegate<T> {
        /**
         * Perform the desired action on the given object.
         *
         * @param object the object to be acted upon
         */
        void execute(T object);
    }

    interface Template extends SafeHtmlTemplates {
        @Template("<img src=\"{0}\" style='cursor:pointer; height: 16px;'/>")
        SafeHtml image(String imageUrl);
    }

    private final SafeHtml html;
    private final Delegate<C> delegate;
    Template template;
//
//    /**
//     * Construct a new {@link ImageActionCell}.
//     *
//     * @param message  the message to display on the button
//     * @param delegate the delegate that will handle events
//     */
//    public ImageActionCell(SafeHtml message, Delegate<C> delegate) {
//
//    }

    /**
     * Construct a new {@link ImageActionCell} with a text String that does not contain
     * HTML markup.
     *
     * @param text     the text to display on the button
     * @param delegate the delegate that will handle events
     */
    public ImageActionCell(String text, Delegate<C> delegate) {
        super("click", "keydown");
        this.delegate = delegate;
        if (template == null) {
            template = GWT.create(Template.class);
        }
        this.html = template.image(text);
    }

    @Override
    public void onBrowserEvent(Cell.Context context, Element parent, C value,
                               NativeEvent event, ValueUpdater<C> valueUpdater) {
        super.onBrowserEvent(context, parent, value, event, valueUpdater);
        if ("click".equals(event.getType())) {
            EventTarget eventTarget = event.getEventTarget();
            if (!Element.is(eventTarget)) {
                return;
            }
            if (parent.getFirstChildElement().isOrHasChild(Element.as(eventTarget))) {
                // Ignore clicks that occur outside of the main element.
                onEnterKeyDown(context, parent, value, event, valueUpdater);
            }
        }
    }

    @Override
    public void render(Cell.Context context, C value, SafeHtmlBuilder sb) {
        sb.append(html);
    }

    @Override
    protected void onEnterKeyDown(Cell.Context context, Element parent, C value,
                                  NativeEvent event, ValueUpdater<C> valueUpdater) {
        delegate.execute(value);
    }
}
